import { SellerTableDataType } from '@/pages/Statistics/component/SellerTable'
import {
  getChannelStatisticsData,
  getOperateStatisticsData,
  getOrderStatisticsData,
  getPhotoTypeStatisticsData,
  PhotoTypeStatisticsBO,
} from '@/services/StatisticsService'
import dayjs from 'dayjs'
import { autorun, makeAutoObservable, runInAction } from 'mobx'
import { ChannelStatisticsBO, OperateStatisticsBO, OrderStatisticsBO } from '../../types/Statistics'

function getFollowTypeSum(channelData: ChannelStatisticsBO[], channel: string, followUpType?: string) {
  if (followUpType) {
    return channelData
      .filter((it) => it.channelName === channel && it.followUpType === followUpType)
      .reduce((acc, curr) => acc + curr.count, 0)
  }
  return channelData.filter((it) => it.channelName === channel).reduce((acc, curr) => acc + curr.count, 0)
}

function getFollowTypeAndUserSum(
  channelData: ChannelStatisticsBO[],
  channel: string,
  userName: string,
  followUpType?: string,
) {
  if (followUpType) {
    return channelData
      .filter((it) => it.channelName === channel && it.followUpType === followUpType && it.userName === userName)
      .reduce((acc, curr) => acc + curr.count, 0)
  }
  return channelData
    .filter((it) => it.channelName === channel && it.userName === userName)
    .reduce((acc, curr) => acc + curr.count, 0)
}

class StatisticsModel {
  startTime: string = dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss') // 统计开始时间
  endTime: string = dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss') // 统计结束时间

  constructor() {
    makeAutoObservable(this, {}, { autoBind: true })
    autorun(() => {
      this.getChannelDataAsync().then()
      this.getOrderStatisticsDataAsync().then()
      this.getOperateStatisticsDataAsync().then()
      this.getGoodsDataAsync().then()
    })
  }

  /* ******************* 按渠道统计 ******************* */
  isPercent: boolean = false
  channelData: ChannelStatisticsBO[] = [] // [渠道,跟进状态]统计数据
  channelFilterUserName?: string
  /**
   * 从后端获取按渠道统计的数据
   */
  getChannelDataAsync = async () => {
    console.log('获取渠道统计数据')
    let data = await getChannelStatisticsData(this.startTime, this.endTime)
    runInAction(() => {
      this.channelData = data
    })
  }

  /**
   * 切换图表是否为百分比
   */
  toggleChannelPercent() {
    this.isPercent = !this.isPercent
  }

  setChannelFilterUserName = (userName: string) => {
    this.channelFilterUserName = userName
  }

  resetChannelFilter() {
    this.channelFilterUserName = undefined
  }

  get channelTableData() {
    let data = this.channelData.map((it) => ({
      userName: it.userName,
      channelName: it.channelName,
      value: it.count,
      followUpType: it.followUpType,
    }))
    return data
  }

  get channelUserPieData() {
    return this.channelData.reduce((acc, curr) => {
      let temp = acc.find((it) => it.userName === curr.userName)
      if (temp !== undefined) {
        temp.value += curr.count
      } else {
        acc.push({
          userName: curr.userName,
          value: curr.count,
        })
      }
      return acc
    }, [] as { userName: string; value: number }[])
  }

  getChannelDataByUserName(userName: string) {
    return this.channelTableData.filter((it) => it.userName === userName)
  }

  /* ******************* 按订单和拍摄状态统计 ******************* */
  orderData: OrderStatisticsBO[] = []
  orderFilterUserName?: string
  orderIsPercent = false

  getOrderStatisticsDataAsync = async () => {
    let data = await getOrderStatisticsData(this.startTime, this.endTime)
    runInAction(() => {
      this.orderData = data
    })
  }

  get orderColumnData() {
    if (this.orderFilterUserName) {
      return this.orderData.filter((it) => it.userName === this.orderFilterUserName)
    }
    return this.orderData
  }

  get orderGoodsPieData() {
    return this.orderData.reduce((acc, curr) => {
      let temp = acc.find((it) => it.goodsName === curr.goodsName)
      if (temp) {
        temp.value += curr.count
      } else {
        acc.push({
          goodsName: curr.goodsName,
          value: curr.count,
        })
      }
      return acc
    }, [] as { goodsName: string; value: number }[])
  }

  get orderPhotoTypePieData() {
    return this.orderData.reduce((acc, curr) => {
      let temp = acc.find((it) => it.photoType === curr.photoType)
      if (temp) {
        temp.value += curr.count
      } else {
        acc.push({
          photoType: curr.photoType,
          value: curr.count,
        })
      }
      return acc
    }, [] as { photoType: string; value: number }[])
  }

  get orderUserPieData() {
    return this.orderData.reduce((acc, curr) => {
      let temp = acc.find((it) => it.userName === curr.userName)
      if (temp) {
        temp.value += curr.count
      } else {
        acc.push({
          userName: curr.userName,
          value: curr.count,
        })
      }
      return acc
    }, [] as { userName: string; value: number }[])
  }

  setOrderFilterUserName(userName?: string) {
    this.orderFilterUserName = userName
  }

  toggleOrderPercent() {
    this.orderIsPercent = !this.orderIsPercent
  }

  resetOrderFilter() {
    this.orderFilterUserName = undefined
  }

  /* ******************* 运营数据 ******************* */
  operateData: OperateStatisticsBO[] = []
  lastMonthOperateData: OperateStatisticsBO[] = []
  getOperateStatisticsDataAsync = async () => {
    let data = await getOperateStatisticsData(this.startTime, this.endTime)
    // 获取上个月的统计数据，用户计算环比
    let lastMonthData = await getOperateStatisticsData(
      dayjs(this.startTime).subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss'),
      dayjs(this.endTime).subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss'),
    )
    // 处理数据
    lastMonthData.forEach((it) => {
      it.orderAchievement = it.orderAchievement / 100
      it.channelDeliverFee = it.channelDeliverFee / 100
      it.channelROI = Math.round((it.orderAchievement / it.channelDeliverFee) * 100) / 100
      it.channelSignalValue = Math.round((it.channelDeliverFee / it.channelCurrent) * 100) / 100
    })
    data.forEach((it) => {
      let lastMonth: OperateStatisticsBO =
        lastMonthData.find((last) => last.channelName === it.channelName) ||
        ({
          channelBudget: 0,
          channelCurrent: 0,
          channelName: it.channelName,
          channelSignalTarget: 0,
          channelTarget: 0,
          orderAchievement: 0,
          channelDeliverFee: 0,
          channelROI: 0,
          channelSignalValue: 0,
          channelSignalMoM: 0,
          orderAchievementMoM: 0,
        } as OperateStatisticsBO)
      it.orderAchievement = it.orderAchievement / 100
      it.channelDeliverFee = it.channelDeliverFee / 100
      it.channelROI = Math.round((it.orderAchievement / it.channelDeliverFee) * 100) / 100
      it.channelSignalValue = Math.round((it.channelDeliverFee / it.channelCurrent) * 100) / 100 || 0
      it.targetPre = Math.round((it.channelCurrent / it.channelTarget) * 10000) / 100

      let lastChannelSignalValue: number = lastMonth.channelSignalValue || 0
      it.channelSignalMoM =
        Math.round(((it.channelSignalValue - lastChannelSignalValue) / lastChannelSignalValue) * 10000) / 100 || 0
      let lastOrderAchievement: number = lastMonth.orderAchievement || 0
      it.orderAchievementMoM =
        Math.round(((it.orderAchievement - lastOrderAchievement) / lastOrderAchievement) * 10000) / 100 || 0
    })
    this.operateData = data
  }

  /* ******************* 渠道数据 NEW ******************* */
  calc(data: SellerTableDataType) {
    let all = data.field1 || 0
    data.V = all - data.VF
    data.VP = Math.round((data.V / all) * 10000) / 100
    data.VP = Number.isNaN(data.VP) ? 0 : data.VP
    data.WP = Math.round(((data.V - data.W) / data.V) * 10000) / 100
    data.WP = Number.isNaN(data.WP) ? 0 : data.WP
    data.CP = Math.round((data.C / data.V) * 10000) / 100
    data.CP = Number.isNaN(data.CP) ? 0 : data.CP
    data.CCP = Math.round((data.CC / data.V) * 10000) / 100
    data.CCP = Number.isNaN(data.CCP) ? 0 : data.CCP
    data.DP = Math.round((data.D / all) * 10000) / 100
    data.DP = Number.isNaN(data.DP) ? 0 : data.DP
    data.SP = Math.round((data.S / data.V) * 10000) / 100
    data.SP = Number.isNaN(data.SP) ? 0 : data.SP
    data.XP = Math.round((data.X / data.V) * 10000) / 100
    data.XP = Number.isNaN(data.XP) ? 0 : data.XP
    data.FP = Math.round((data.F / data.W) * 10000) / 100
    data.FP = Number.isNaN(data.FP) ? 0 : data.FP
    data.QP = Math.round((data.Q / data.C) * 10000) / 100
    data.QP = Number.isNaN(data.QP) ? 0 : data.QP
    data.VDP = Math.round((data.D / data.V) * 10000) / 100
    data.VDP = Number.isNaN(data.VDP) ? 0 : data.VDP
    data.VP = Math.round((data.V / all) * 10000) / 100
    data.VP = Number.isNaN(data.VP) ? 0 : data.VP
  }

  calculateData = (
    channelData: ChannelStatisticsBO[],
    channel: string,
    sellerSet: Set<string>,
  ): SellerTableDataType => {
    // 渠道数据
    // 合并数据
    let data: SellerTableDataType = {
      name: channel,
      key: `${channel}`,
      ADP: 0,
      C: getFollowTypeSum(channelData, channel, 'C未推'),
      CC: getFollowTypeSum(channelData, channel, 'CC已推套餐'),
      CCP: 0,
      CP: 0,
      D: getFollowTypeSum(channelData, channel, 'D成交'),
      DP: 0,
      F: getFollowTypeSum(channelData, channel, '重复'),
      FP: 0,
      Q: getFollowTypeSum(channelData, channel, 'Q去别家了'),
      QP: 0,
      S: getFollowTypeSum(channelData, channel, 'S删除'),
      SP: 0,
      V: 0,
      VF: getFollowTypeSum(channelData, channel, '加V不成功'),
      VDP: 0,
      VP: 0,
      W: getFollowTypeSum(channelData, channel, 'W不开口'),
      WP: 0,
      X: getFollowTypeSum(channelData, channel, 'X无效'),
      XP: 0,
      field1: getFollowTypeSum(channelData, channel),
    }
    this.calc(data)

    // 计算数据

    // 员工数据
    let sellerResult: SellerTableDataType[] = []
    for (const seller of sellerSet) {
      let sellerData: SellerTableDataType = {
        name: seller,
        key: `${channel}_${seller}`,
        ADP: 0,
        C: getFollowTypeAndUserSum(channelData, channel, seller, 'C未推'),
        CC: getFollowTypeAndUserSum(channelData, channel, seller, 'CC已推套餐'),
        CCP: 0,
        CP: 0,
        D: getFollowTypeAndUserSum(channelData, channel, seller, 'D成交'),
        DP: 0,
        F: getFollowTypeAndUserSum(channelData, channel, seller, '重复'),
        FP: 0,
        Q: getFollowTypeAndUserSum(channelData, channel, seller, 'Q去别家了'),
        QP: 0,
        S: getFollowTypeAndUserSum(channelData, channel, seller, 'S删除'),
        SP: 0,
        V: 0,
        VF: getFollowTypeAndUserSum(channelData, channel, seller, '加V不成功'),
        VDP: 0,
        VP: 0,
        W: getFollowTypeAndUserSum(channelData, channel, seller, 'W不开口'),
        WP: 0,
        X: getFollowTypeAndUserSum(channelData, channel, seller, 'X无效'),
        XP: 0,
        field1: getFollowTypeAndUserSum(channelData, channel, seller),
      }
      this.calc(sellerData)
      sellerResult.push(sellerData)
    }
    data.children = sellerResult
    return data
  }

  get sellerTableDataType(): SellerTableDataType[] {
    let channelSet = new Set(this.channelData.map((it) => it.channelName))
    console.log(channelSet)
    let sellerSet = new Set(this.channelData.map((it) => it.userName))
    console.log(sellerSet)
    let result: SellerTableDataType[] = []
    for (let string of channelSet) {
      let dataType: SellerTableDataType = this.calculateData(this.channelData, string, sellerSet)
      result.push(dataType)
    }
    console.log(result)
    return result
  }

  /* ******************* 按套系统计 ******************* */
  photoTypeDataBOList: PhotoTypeStatisticsBO[] = []
  photoTypeDataAllBO: PhotoTypeStatisticsBO = {
    field1: 0,
    field2: 0,
    field3: 0,
    field4: 0,
    field5: 0,
    field6: 0,
    field7: 0,
    field8: 0,
    sellerName: '汇总',
    userId: '0',
  }

  calculateTheShootingType(bo: PhotoTypeStatisticsBO, base: number, allBo?: PhotoTypeStatisticsBO) {
    bo.field1Percentage = Math.round((bo.field1 / (allBo?.field1 || base)) * 10000) / 100
    bo.field2Percentage = Math.round((bo.field2 / (allBo?.field2 || base)) * 10000) / 100
    bo.field3Percentage = Math.round((bo.field3 / (allBo?.field3 || base)) * 10000) / 100
    bo.field4Percentage = Math.round((bo.field4 / (allBo?.field4 || base)) * 10000) / 100
    bo.field5Percentage = Math.round((bo.field5 / (allBo?.field5 || base)) * 10000) / 100
    bo.field6Percentage = Math.round((bo.field6 / (allBo?.field6 || base)) * 10000) / 100
    bo.field7Percentage = Math.round((bo.field7 / (allBo?.field7 || base)) * 10000) / 100
    bo.field8Percentage = Math.round((bo.field8 / (allBo?.field8 || base)) * 10000) / 100
  }

  async getGoodsDataAsync() {
    let data = await getPhotoTypeStatisticsData(this.startTime, this.endTime)
    let allBO: PhotoTypeStatisticsBO = data.reduce((acc, curr) => {
      acc.field1 += curr.field1
      acc.field2 += curr.field2
      acc.field3 += curr.field3
      acc.field4 += curr.field4
      acc.field5 += curr.field5
      acc.field6 += curr.field6
      acc.field7 += curr.field7
      acc.field8 += curr.field8
      return acc
    }, JSON.parse(JSON.stringify(this.photoTypeDataAllBO)))
    let allOrderCount =
      allBO.field1 + allBO.field2 + allBO.field3 + allBO.field4 + allBO.field5 + allBO.field6 + allBO.field7

    this.calculateTheShootingType(allBO, allOrderCount)
    // 计算汇总数据

    data.forEach((it) => this.calculateTheShootingType(it, 1, allBO))
    // 计算百分比
    runInAction(() => {
      this.photoTypeDataAllBO = allBO
      this.photoTypeDataBOList = data
    })
  }
}

export default StatisticsModel
export const statisticsModel = new StatisticsModel()
